/*
  audio.cpp
*/

#include <windows.h>
#define BASSDEF(f) (WINAPI *f)	// define the functions as pointers
#include "bass.h"

#define LOADBASSFUNCTION(f) *((void**)&f)=(void*)GetProcAddress(hbass,#f)

typedef DWORD hsound;

static HINSTANCE hbass;

extern bool auinit (HWND hwnd)
{
	if (hbass) return true;

	hbass = LoadLibrary("bass.dll");
	if (!hbass) return false;

	LOADBASSFUNCTION(BASS_GetVersion);
	if (BASS_GetVersion()!=MAKELONG(2,2))
		return false;

	LOADBASSFUNCTION(BASS_GetDeviceDescription);
	LOADBASSFUNCTION(BASS_Init);
	LOADBASSFUNCTION(BASS_Free);
	LOADBASSFUNCTION(BASS_Start);
	LOADBASSFUNCTION(BASS_Stop);
	LOADBASSFUNCTION(BASS_SetConfig);

	LOADBASSFUNCTION(BASS_SampleLoad);
	LOADBASSFUNCTION(BASS_SampleCreate);
	LOADBASSFUNCTION(BASS_SampleCreateDone);
	LOADBASSFUNCTION(BASS_SampleGetInfo);
	LOADBASSFUNCTION(BASS_SampleGetChannel);
	LOADBASSFUNCTION(BASS_SampleFree);
	
	LOADBASSFUNCTION(BASS_MusicLoad);
	LOADBASSFUNCTION(BASS_MusicFree);

	LOADBASSFUNCTION(BASS_StreamCreateFile);
	LOADBASSFUNCTION(BASS_StreamFree);
	
	LOADBASSFUNCTION(BASS_ChannelGetInfo);
	LOADBASSFUNCTION(BASS_ChannelGetAttributes);
	LOADBASSFUNCTION(BASS_ChannelSetAttributes);
	LOADBASSFUNCTION(BASS_ChannelSetFlags);
	LOADBASSFUNCTION(BASS_ChannelGetData);
	LOADBASSFUNCTION(BASS_ChannelPlay);
	LOADBASSFUNCTION(BASS_ChannelPause);
	LOADBASSFUNCTION(BASS_ChannelStop);
	LOADBASSFUNCTION(BASS_ChannelIsActive);
	LOADBASSFUNCTION(BASS_ChannelGetLength);
	LOADBASSFUNCTION(BASS_ChannelGetPosition);
	LOADBASSFUNCTION(BASS_ChannelSetPosition);
	LOADBASSFUNCTION(BASS_ChannelSeconds2Bytes);
	LOADBASSFUNCTION(BASS_ChannelBytes2Seconds);

  if (!BASS_Init (1, 44100, 0, hwnd, NULL))
    return false;
    
  BASS_Start();
  return true;
}

extern void aufree ()
{
	if (!hbass) return;
  BASS_Stop();
  BASS_Free();
}

extern hsound auload (char *file)
{
  return BASS_SampleLoad(FALSE, file, 0, 0, 4, BASS_SAMPLE_OVER_VOL);
}

extern void auplay (hsound sound, int volume, int pan, float pitch, bool loop)
{
	HCHANNEL chn;
	BASS_SAMPLE info;
	BASS_SampleGetInfo(sound, &info);
	chn = BASS_SampleGetChannel (sound, FALSE);
	BASS_ChannelSetAttributes(chn, (int)(pitch*info.freq), volume, pan);
	BASS_ChannelSetFlags(chn, loop ? BASS_SAMPLE_LOOP:0);
	BASS_ChannelPlay (chn, TRUE);
}

extern void aupause (hsound sound)
{
	HCHANNEL chn;
	chn = BASS_SampleGetChannel (sound, FALSE);
	BASS_ChannelPause(chn);
}

extern void auresume (hsound sound)
{
	HCHANNEL chn;
	chn = BASS_SampleGetChannel (sound, FALSE);
	BASS_ChannelPlay(chn, FALSE);
}

extern void austop (hsound sound)
{
	HCHANNEL chn;
	chn = BASS_SampleGetChannel (sound, FALSE);
	BASS_ChannelStop(chn);
}

extern void austopall ()
{
	BASS_Stop();
	BASS_Start();
}